"""
日志模块
提供统一的日志记录功能，支持文件和控制台输出，以及不同级别的日志
"""

import os
import logging
import logging.handlers
from datetime import datetime
from pathlib import Path
from typing import Optional, Union, Dict

# 默认配置
DEFAULT_CONFIG = {
    'log_level': logging.INFO,
    'log_format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s',
    'date_format': '%Y-%m-%d %H:%M:%S',
    'log_dir': Path(__file__).parent.parent.parent.joinpath('logs'),
    'max_bytes': 10 * 1024 * 1024,  # 10MB
    'backup_count': 5,
    'file_name_template': '{name}#test_execution-{timestamp}.log'
}


class LoggerManager:
    """日志管理器，负责创建和管理日志实例"""

    _instances: Dict[str, logging.Logger] = {}
    _console_handler = None  # 添加类级别的控制台处理器

    @classmethod
    def get_logger(cls, name: Optional[str] = None, log_name: Optional[str] = None, write_to_file: bool = True,
                   **kwargs) -> logging.Logger:
        if not name:
            import inspect
            frame = inspect.currentframe()
            caller_frame = frame.f_back
            name = caller_frame.f_globals['__name__']

        # 如果已经存在相同名称的logger，直接返回
        if name in cls._instances:
            return cls._instances[name]

        # 创建新的logger
        logger = logging.getLogger(name)
        logger.setLevel(kwargs.get('log_level', DEFAULT_CONFIG['log_level']))
        logger.propagate = False  # 防止日志传播到root logger

        # 确保只添加一次控制台处理器
        if not cls._console_handler:
            cls._console_handler = logging.StreamHandler()
            formatter = logging.Formatter(
                kwargs.get('log_format', DEFAULT_CONFIG['log_format']),
                kwargs.get('date_format', DEFAULT_CONFIG['date_format'])
            )
            cls._console_handler.setFormatter(formatter)

        # 检查是否已经有控制台处理器
        has_console_handler = any(isinstance(h, logging.StreamHandler) and not isinstance(h, logging.FileHandler)
                                  for h in logger.handlers)

        if not has_console_handler:
            logger.addHandler(cls._console_handler)

        # 如果需要写入文件且还没有文件处理器
        if write_to_file and not any(isinstance(h, logging.FileHandler) for h in logger.handlers):
            log_dir = Path(kwargs.get('log_dir', DEFAULT_CONFIG['log_dir']))
            log_dir.mkdir(parents=True, exist_ok=True)

            timestamp = datetime.now().strftime('%Y%m%d_%H%M%S')
            log_name = log_name or name.split('.')[-1]
            file_name = DEFAULT_CONFIG['file_name_template'].format(
                name=log_name,
                timestamp=timestamp
            )

            file_handler = logging.handlers.RotatingFileHandler(
                log_dir / file_name,
                maxBytes=kwargs.get('max_bytes', DEFAULT_CONFIG['max_bytes']),
                backupCount=kwargs.get('backup_count', DEFAULT_CONFIG['backup_count']),
                encoding='utf-8'
            )
            file_handler.setFormatter(cls._console_handler.formatter)
            logger.addHandler(file_handler)

        cls._instances[name] = logger
        return logger


    @classmethod
    def set_level(cls, level: Union[int, str], logger_name: Optional[str] = None):
        """设置日志级别

        Args:
            level: 日志级别，可以是 int 或字符串
            logger_name: 日志器名称，默认修改所有日志器
        """
        if isinstance(level, str):
            level = getattr(logging, level.upper())

        if logger_name and logger_name in cls._instances:
            logger = cls._instances[logger_name]
            logger.setLevel(level)
            for handler in logger.handlers:
                handler.setLevel(level)
        else:
            for logger in cls._instances.values():
                logger.setLevel(level)
                for handler in logger.handlers:
                    handler.setLevel(level)

    @classmethod
    def clean_old_logs(cls, days: int = 7):
        """清理指定天数之前的日志文件

        Args:
            days: 保留的天数，默认7天
        """
        log_dir = Path(DEFAULT_CONFIG['log_dir'])
        if not log_dir.exists():
            return

        current_time = datetime.now().timestamp()
        for log_file in log_dir.glob('*.log*'):
            file_time = os.path.getmtime(log_file)
            if (current_time - file_time) // (24 * 3600) >= days:
                try:
                    log_file.unlink()
                except Exception as e:
                    print(f"删除日志文件失败: {log_file}, 错误: {e}")


# 创建默认日志实例
# logger = LoggerManager.get_logger()

# 定期清理旧日志文件
LoggerManager.clean_old_logs()

if __name__ == '__main__':
    # 使用示例
    logger = LoggerManager.get_logger('test_logger',write_to_file=False)
    logger.info('这是一条信息日志')
    logger.error('这是一条错误日志')

    # 修改日志级别
    LoggerManager.set_level('DEBUG')
    logger.debug('这是一条调试日志')

